package com.hdoit.ares.web.home.apis;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.github.binarywang.wxpay.bean.request.WxPayBaseRequest;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.hdoit.ares.web.cbase.AppWechatConfiguration;
import com.hdoit.ares.web.cbase.AppWechatPayService;
import com.tennetcn.common.logical.viewmodel.wechat.GoodsInfo;
import com.tennetcn.common.logical.wechat.model.WechatGoods;
import com.tennetcn.common.logical.wechat.model.WechatOrder;
import com.tennetcn.common.logical.wechat.model.WechatOrderGoods;
import com.tennetcn.common.logical.wechat.service.IWechatGoodsService;
import com.tennetcn.common.logical.wechat.service.IWechatOrderGoodsService;
import com.tennetcn.common.logical.wechat.service.IWechatOrderService;
import com.tennetcn.common.selfcommon.enums.wechat.WechatOrderStatus;
import com.tennetcn.common.utils.CommonUtils;
import com.tennetcn.common.utils.DateUtils;
import com.tennetcn.common.utils.JsonUtils;
import com.tennetcn.common.utils.RandomUtils;
import com.tennetcn.common.utils.StringHelper;
import com.tennetcn.component.webapi.BaseApi;
import com.tennetcn.component.wechat.config.WechatConfigModel;
import com.tennetcn.plugins.devshorts.enumerable.Enumerable;

@Controller
@RequestMapping(value = "/api/v1/appPayWexinApis/",method = { RequestMethod.GET,RequestMethod.POST},produces="application/json;charset=utf-8")
@Api(value = "/api/v1/appPayWexinApis/")
@CrossOrigin(origins = "*",maxAge = 3600)
public class AppPayWexinApis extends BaseApi{
	
	private AppWechatPayService appWechatPayService;
	private IWechatGoodsService wechatGoodsService;
	private IWechatOrderService wechatOrderService;
	private IWechatOrderGoodsService wechatOrderGoodsService;
	
	public IWechatOrderGoodsService getWechatOrderGoodsService() {
		return wechatOrderGoodsService;
	}
	@Resource
	public void setWechatOrderGoodsService(IWechatOrderGoodsService wechatOrderGoodsService) {
		this.wechatOrderGoodsService = wechatOrderGoodsService;
	}
	
	public IWechatOrderService getWechatOrderService() {
		return wechatOrderService;
	}
	
	@Resource
	public void setWechatOrderService(IWechatOrderService wechatOrderService) {
		this.wechatOrderService = wechatOrderService;
	}
	
	public IWechatGoodsService getWechatGoodsService() {
		return wechatGoodsService;
	}
	
	@Resource
	public void setWechatGoodsService(IWechatGoodsService wechatGoodsService) {
		this.wechatGoodsService = wechatGoodsService;
	}
	
	public AppWechatPayService getAppWechatPayService() {
		return appWechatPayService;
	}

	@Resource
	public void setAppWechatPayService(AppWechatPayService appWechatPayService) {
		this.appWechatPayService = appWechatPayService;
	}


	private final String payInfoViewName="payInfo";
	
	@ResponseBody
	@RequestMapping(value = payInfoViewName)
	@ApiOperation(notes = payInfoViewName,httpMethod = "POST",value = "获取微信单号")
	public String getPayInfo(@RequestBody List<GoodsInfo> goodsInfos){
		//定义一个resultMap
		Map<String,Object> resultMap=new HashMap<String, Object>();
	
		//检查goodsInfo是否为空，空就返回false，否则返回true
		if(!checkGoodsInfos(goodsInfos, resultMap)){
			return JsonUtils.toJson(resultMap);
		}
	
		try {
			WxPayUnifiedOrderRequest request = getPayInfoRequest();
			
			//创建一个订单
			
			WechatOrder wechatOrder = createWechatOrder();
			
			request.setOutTradeNo(wechatOrder.getTradeNo());
			List<WechatOrderGoods> orderGoodsList=getWechatOrderGoods(wechatOrder.getTradeNo(),goodsInfos);
			if(orderGoodsList==null||orderGoodsList.size()==0){
				resultMap.put("result", "error");
				resultMap.put("message", "商品信息为空");
				return JsonUtils.toJson(resultMap);
			}
			
			OrderGoods og=getSumPrice(orderGoodsList, goodsInfos);
			
			wechatOrder.setTotalFee(og.getSumPrice());
			wechatOrder.setName(og.getName());
			
			request.setTotalFee(WxPayBaseRequest.yuanToFee(String.valueOf(og.getSumPrice())));
			request.setBody(orderGoodsList.stream().findFirst().get().getName());
			
			Map<String, String>payInfoMap =  this.appWechatPayService.getPayInfo(request);
			payInfoMap.put("tradeNo", wechatOrder.getTradeNo());

			wechatOrder.setAttach(request.getAttach());
			wechatOrder.setPrepayId(payInfoMap.get("prepayId"));
			wechatOrder.setTimeStart(request.getTimeStart());
			wechatOrder.setOrderStatus(WechatOrderStatus.paying);

			if(wechatOrderService.addModel(wechatOrder)){
				wechatOrderGoodsService.insertListEx(orderGoodsList);
			}
			resultMap.put("result", "success");
			resultMap.put("payInfo", payInfoMap);
		} catch (WxPayException e) {
			e.printStackTrace();
			resultMap.put("result", "error");
			resultMap.put("message", "构建订单逻辑出错");
		}
	
		return JsonUtils.toJson(resultMap);
		
	}
	
	protected OrderGoods getSumPrice(List<WechatOrderGoods> orderGoodsList, List<GoodsInfo> goodsInfos){
		double sumPrice=0.0;
		List<String> nameList=new ArrayList<String>();
		
		for (WechatOrderGoods orderGoods:orderGoodsList) {
			GoodsInfo goodsInfo=Enumerable.init(goodsInfos).filter(gi->{return gi.getGoodsId().equals(orderGoods.getGoodsId());}).first();
			
			sumPrice+=orderGoods.getCount()*(orderGoods.getPrice()-goodsInfo.getReduce());
			nameList.add(orderGoods.getName());
		}
		
		OrderGoods og=new OrderGoods();
		og.setName(StringHelper.join(nameList));
		og.setSumPrice(sumPrice);
		
		return og;
	}
	protected WxPayUnifiedOrderRequest getPayInfoRequest(){
		
		//定义一个新的参数请求
		WxPayUnifiedOrderRequest request=new WxPayUnifiedOrderRequest();

		//微信配置参数模型
		WechatConfigModel wcm=getWechatConfigModel();
		//公众号Id，AppId
		request.setAppid(wcm.getAppId());
		//商户号
		request.setMchId(wcm.getMchId());
		//APP和网页支付提交用户端ip，Native支付填调用微信支付API的机器IP
		request.setSpbillCreateIp(wcm.getSpbillCreateIp());
		//接收微信支付异步通知回调地址，通知url必须为直接可访问的url，不能携带参数
		request.setNotifyURL(wcm.getNotifyURL());
		//交易类型， JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付
		request.setTradeType(wcm.getTradeType());
	
		//订单生成时间，格式为yyyyMMddHHmmss，如2009年12月25日9点10分10秒表示为20091225091010。其他详见时间规则
		request.setTimeStart(DateUtils.convertDate2String("yyyyMMddHHmmss", new Date()));
		
		return request;
	}

	
	protected WechatOrder createWechatOrder(){
		//得到微信参数配置
		WechatConfigModel wcm=getWechatConfigModel();
		//得到一个订单
		WechatOrder wechatOrder=new WechatOrder();
		//公众号ID
		wechatOrder.setAppId(wcm.getAppId());
		//订单ID
		wechatOrder.setTradeNo(getTradeNo(wcm.getOrgCode()));
		//商户号
		wechatOrder.setMchId(wcm.getMchId());
		//交易类型
		wechatOrder.setTradeType(wcm.getTradeType());
		
		return wechatOrder;
	}
	
	
	protected String getTradeNo(String orgCode){
		return orgCode+DateUtils.convertDate2String("yyyyMMddHHmmssSSS", new Date())+RandomUtils.randomNumbers(6);
	}
	
	protected WechatConfigModel getWechatConfigModel(){
		return AppWechatConfiguration.getInstance().wechatConfigModel;
	}
	

	private boolean checkGoodsInfos(List<GoodsInfo> goodsInfos, Map<String, Object> resultMap) {
		
		//如果商品列表为空，返回的resultMap
		if (goodsInfos == null) {
			resultMap.put("result", "error");
			resultMap.put("message", "商品信息为空");
			return false;
		}
		
		for (int i = 0; i < goodsInfos.size(); i++) {
			//定义得到的goodsInfo
			GoodsInfo goodsInfo = goodsInfos.get(i);
			//如果id为空获取数量为空，返回false
			if (StringUtils.isEmpty(goodsInfo.getGoodsId()) || StringUtils.isEmpty(goodsInfo.getCounts())) {
				resultMap.put("result", "error");
				resultMap.put("message", "商品或数量不能为空");
				return false;
			}
		}
		return true;
	}
	
	protected List<WechatOrderGoods> getWechatOrderGoods(String orderId,List<GoodsInfo> goodsInfos){
		//得到一个商品id的list集合
		List<String> goodsIds=Enumerable.init(goodsInfos).map(goodsInfo->{return goodsInfo.getGoodsId();}).toList();
		//查询商品List
		List<WechatGoods> wechatGoodsList=wechatGoodsService.queryListByIds(goodsIds);

		List<WechatOrderGoods> wechatOrderGoods=new ArrayList<WechatOrderGoods>();
		for (WechatGoods wechatGoods : wechatGoodsList) {
			WechatOrderGoods orderGoods=new WechatOrderGoods();
			
			orderGoods.setId(CommonUtils.getKeyId());
			orderGoods.setGoodsId(wechatGoods.getId());
			orderGoods.setOrderId(orderId);
			orderGoods.setDescription(wechatGoods.getDescription());
			orderGoods.setName(wechatGoods.getName());
			
			orderGoods.setPrice(wechatGoods.getDealPrice());
			orderGoods.setType(wechatGoods.getType());
			orderGoods.setSubType(wechatGoods.getSubType());
			orderGoods.setGoodsMark(wechatGoods.getGoodsMark());
			
			int count=Enumerable.init(goodsInfos).filter(goodsInfo->wechatGoods.getId().equals(goodsInfo.getGoodsId())).first().getCounts();
			orderGoods.setCount(count);
			
			wechatOrderGoods.add(orderGoods);
		}
		return wechatOrderGoods;
	}
	
	
	class OrderGoods{
		private double sumPrice;
		
		private String name;

		public double getSumPrice() {
			return sumPrice;
		}

		public void setSumPrice(double sumPrice) {
			this.sumPrice = sumPrice;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}
	}
	
}
